<template>
  <view
    class="c-pload-avatar"
    :class="ggclass"
    :style="{
      borderRadius: radius,
      width: $rpxunit(size),
      height: $rpxunit(size),
    }"
  >
    <slot>
      <image
        class="img"
        :style="{
          borderRadius: radius,
          width: $rpxunit(size),
          height: $rpxunit(size),
        }"
        :src="imgFilter(valUrl)"
        @click="onImage"
        @load="load"
        @error="error"
      >
      </image>
      <!-- #ifndef MP-TOUTIAO -->
      <c-loading
        class="loding"
        isOpenPattern
        :size="lodingS"
        :loading="isloding"
      ></c-loading>
      <!-- #endif -->
      <!-- #ifndef MP-WEIXIN -->
      <view class="upload-button" v-if="isUpload" @click="upload">
        <text
          class="iconfont icon-paizhao"
          style="color: #fff"
          :style="{ fontSize }"
        ></text>
      </view>
      <!-- #endif -->
      <!-- #ifdef MP-WEIXIN -->
      <button
        class="upload-button"
        v-if="isUpload"
        open-type="chooseAvatar"
        @chooseavatar="onChooseAvatar"
      >
        <text
          class="iconfont icon-paizhao"
          style="color: #fff"
          :style="{ fontSize }"
        ></text>
      </button>
      <!-- #endif -->
    </slot>
  </view>
</template>

<script setup lang="ts">
import {
  computed,
  defineProps,
  getCurrentInstance,
  onMounted,
  reactive,
  toRefs,
} from "vue";
const { proxy } = getCurrentInstance() as any;
const $rpxunit = proxy.$rpxunit;
//@ts-ignore
import { defaultAvatar } from "../../static/img/base64.js";
//@ts-ignore
import { imgPreview } from "../ways/img.js";
import { imgFilter } from "../ways/filter";

const props = defineProps({
  ggclass: {
    type: String,
    default: "",
  },
  radius: {
    type: String,
    default: "",
  },
  size: {
    type: String,
    default: "",
  },
  modelValue: {
    type: String,
    default: "",
  },
  api: {
    type: String,
    default: "/upload/image",
  },
  isPreview: {
    type: Boolean,
    default: false,
  },
  isUpload: {
    type: Boolean,
    default: false,
  },
  lazy: {
    type: Boolean,
    default: false,
  },
  lodingSize: {
    type: [String, Number],
    default: "",
  },
  range_key: {
    type: String,
    default: "url",
  },
});
const state = reactive({
  isloding: true,
  lazySrc: "",
});
const { isloding } = toRefs(state);

const valUrl = computed({
  get() {
    // if (!this.lazy) {
    // 	this.authenticate()
    // }
    let a = props.lazy ? state.lazySrc : props.modelValue;
    return a || defaultAvatar;
  },
  set(val) {
    proxy.$emit("input", val);
    proxy.$emit("change", val);
  },
});
const fontSize = computed(() => {
  return `${parseInt(props.size) / 4}rpx`;
});
const lodingS = computed(() => {
  if (props.lodingSize) return props.lodingSize;
  let unit = String(props.size).match(/[a-z|A-Z|'%']+/gi);
  return `${parseInt(props.size) / 2}${unit}`;
});

onMounted(() => {
  if (props.lazy) {
    observer(".c-pload-avatar", (res: any) => {
      state.lazySrc = props.modelValue || defaultAvatar;
      // this.authenticate()
    });
  }
});

const observer = (node: string, callback: Function) => {
  let observer = uni.createIntersectionObserver(proxy);
  let ob = observer.relativeToViewport();
  ob.observe(node, (res) => {
    callback(res);
    observer.disconnect();
  });
};
// authenticate() {
// 	setTimeout(() => {
// 		if (this.lazy) {
// 			if (!this.lazySrc) {
// 				this.lazySrc = ' '
// 			}
// 		} else {
// 			if (!this.modelValue) {
// 				this.valUrl = ' '
// 			}
// 		}
// 	}, 10000)
// },
const load = () => {
  state.isloding = false;
};
const error = () => {
  state.isloding = false;
  valUrl.value = defaultAvatar;
};
const onChooseAvatar = async (e: any) => {
  const { avatarUrl } = e.detail;
  valUrl.value = (await uploadFile(avatarUrl)) as string;
};
const onImage = (event: Event) => {
  if (props.isPreview) {
    imgPreview(valUrl.value);
  }
  proxy.$emit("click", event);
  proxy.$emit("tap", event);
};
const upload = () => {
  uni.chooseImage({
    count: 1,
    success: async (res: any) => {
      valUrl.value = (await uploadFile(res.tempFiles[0].path)) as string;
    },
  });
};
/**
 * 上传文件
 * @param {string} v 文件路径
 * @param {string} size 文件大小
 */
const uploadFile = (filePath: string) => {
  uni.showToast({
    title: "上传中...",
    icon: "loading",
  });
  return new Promise(async (ress, err) => {
    uni.uploadFile({
      url: import.meta.env.VITE_API_URL + props.api,
      filePath,
      name: "file",
      success: (res) => {
        const data = JSON.parse(res.data);
        let url = data.result[props.range_key];
        ress(url);
      },
      fail(error) {
        err(error);
        console.log(error, "error");
      },
      complete() {
        uni.hideToast();
      },
    });
  });
};
</script>

<style lang="scss" scoped>
.c-pload-avatar {
  width: 200rpx;
  height: 200rpx;
  border-radius: 200rpx;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;

  // border: 2rpx solid #fff;
  .img {
    width: 200rpx;
    height: 200rpx;
    border-radius: 200rpx;
  }
}

.upload-button {
  position: absolute;
  right: -10rpx;
  bottom: -5rpx;
  padding: 10rpx;
  background: $uni-color-main;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  border-radius: 64rpx;
  line-height: 1;
}

.loding {
  position: absolute;
}
</style>